package com.yss.config;

import com.yss.netty.protocol.CommandType;
import com.yss.netty.util.Host;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Slf4j
@Component
@ConfigurationProperties(prefix = "command-type")
public class CommandTypeConfig {

    @Getter
    @Setter
    private Map<String, String> bond;

    private final Map<CommandType, Map<String, Host>> commandTypeHostMapper;

    public CommandTypeConfig() {
        this.commandTypeHostMapper = new HashMap<>();
    }

    @PostConstruct
    public void init() throws IllegalAccessException {
        this.buildCommandTypeHostMapper();
    }

    private void buildCommandTypeHostMapper() throws IllegalAccessException {
        Map<String, CommandType> typeNames = new HashMap<>();
        CommandType[] types = CommandType.values();
        Arrays.stream(types).forEach(type -> typeNames.put(type.name().toUpperCase(), type));

        Field[] fields = CommandTypeConfig.class.getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName().toUpperCase();
            if (typeNames.containsKey(fieldName)) {
                Object val = field.get(this);
                if (val == null || !StringUtils.hasText(String.valueOf(val))) {
                    continue;
                }
                Map<String, Host> nettyRestMap = new HashMap<>();

                HashMap fieldValue = (LinkedHashMap) field.get(this);
                if (fieldValue.containsKey("netty")) {
                    nettyRestMap.put("netty", Host.of((String) fieldValue.get("netty")));
                }
                if (fieldValue.containsKey("rest")) {
                    nettyRestMap.put("rest", Host.ofResourceUrl((String) fieldValue.get("rest")));
                }
                commandTypeHostMapper.put(typeNames.get(fieldName), nettyRestMap);
            }
        }
    }

    public Host getNettyHostByCommandType(CommandType type) {
        return commandTypeHostMapper.get(type).get("netty");
    }

    public Host getRestHostByCommandType(CommandType type) {
        return commandTypeHostMapper.get(type).get("rest");
    }

}
